home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / driverss.zip / TIARA.ASM < prev    next >
Assembly Source File  |  1991-03-25  |  29KB  |  915 lines

  1. version        equ     2
  2.  
  3. ;******************************************************************************;
  4. ;*                                                                            *;
  5. ;*     File: TiaraFTP.ASM                                                     *;
  6. ;*     Auth: Brian Fisher                                                     *;
  7. ;*           Queens University                                                *;
  8. ;*           Computing and Communications Services                            *;
  9. ;*           Rm 2-50 Dupuis Hall                                              *;
  10. ;*           Kingston Ontario                                                 *;
  11. ;*                                                                            *;
  12. ;*     Date: January 24 1990                                                  *;
  13. ;*                                                                            *;
  14. ;*     Purp: (3C501) Packet driver for Tiara Ethernet Card.                   *;
  15. ;*                                                                            *;
  16. ;*============================================================================*;
  17. ;*     Revs: January 25 1990   V 1.6.0 Clean up code and document.            *;
  18. ;*           Feb     24 1991   V 1.8.2 Gets IRQ and I/O info from MCH POS regs*;
  19. ;*                                                                            *;
  20. ;*============================================================================*;
  21. ;*                                                                            *;
  22. ;*     Thanks, Mehdi Safipour, of Tiara Computer Systems, who supplied the    *;
  23. ;*     programming manual and examples.                                       *;
  24. ;*                                                                            *;
  25. ;*============================================================================*;
  26. ;*                                                                            *;
  27. ;*     Logic -                                                                *;
  28. ;*                                                                            *;
  29. ;*     Initialization - classic, by-the-book initialization, with one         *;
  30. ;*     exception:  The manual didn't mention the fact that receive            *;
  31. ;*     interrupts will not always work unless the receive buffer is           *;
  32. ;*     vacuumed.                                                              *;
  33. ;*                                                                            *;
  34. ;*     Byte/Word I/O mode was determined by code ruthlessly copied from       *;
  35. ;*     NI5010.ASM, auth: Russ Nelson.                                         *;
  36. ;*                                                                            *;
  37. ;*     Transmit-no surprises, data goes whoosh]                               *;
  38. ;*                                                                            *;
  39. ;*     Receive-interrupt driven receive makes upcalls to inform the ULP of    *;
  40. ;*     its status.  The 14 byte ethernet header is copied from the card to    *;
  41. ;*     a temporary buffer, to determine the ether-type.  Recv_find is called  *;
  42. ;*     to acquire a buffer from the ULP.  If no buffer, the packet is dropped.*;
  43. ;*     If a buffer is acquired, the packet is copied into it, and recv_copy   *;
  44. ;*     informs the ULP that the data is there.                                *;
  45. ;*                                                                            *;
  46. ;******************************************************************************;
  47. ;
  48.  
  49. DLCR_XMIT_STAT EQU     0               ; EtherStar I/O Register offsets
  50. DLCR_XMIT_MASK EQU     1
  51. DLCR_RECV_STAT EQU     2
  52. DLCR_RECV_MASK EQU     3
  53. DLCR_XMIT_MODE EQU     4
  54. DLCR_RECV_MODE EQU     5
  55. DLCR_ENABLE    EQU     6
  56. DLCR_TDR_LOW   EQU     7
  57. DLCR_NODE_ID   EQU     8
  58. DLCR_TDR_HIGH  EQU     0FH
  59. BMPR_MEM_PORT  EQU     10H
  60. BMPR_PKT_LEN   EQU     12H
  61. BMPR_DMA_ENABLE EQU    14H
  62. PROM_ID        EQU     18H
  63. TMST           EQU     80h
  64. TMT_OK         EQU     80h
  65. BUF_EMPTY      EQU     40h
  66. card_disable   equ     80h             ; written to DLCR_ENABLE to disable card
  67. card_enable    equ     0h              ; written to DLCR_ENABLE to enable card
  68. clear_status   equ     00001111B       ; used to clear status info
  69. ;
  70. ;                      !!!!!!!!--------
  71. ;                      !!!!!!!+--------CLEAR BUS WRITE ERROR
  72. ;                      !!!!!!+---------CLEAR 16 COLLISION
  73. ;                      !!!!!+----------CLEAR COLLISION
  74. ;                      !!!!+-----------CLEAR UNDERFLOW
  75. ;                      !!!+------------NC
  76. ;                      !!+-------------NC
  77. ;                      !+--------------NC
  78. ;                      +---------------NC
  79. ;
  80. no_tx_irqs      equ     0              ; written to clear transmit IRQs
  81. clr_rcv_status  equ     0CFh           ; clears receive status
  82. en_rcv_irqs     equ     10000000B      ; enable receive interrupts
  83. ;
  84. ;                      !!!!!!!!--------
  85. ;                      !!!!!!!+--------ENABLE OVERFLOW
  86. ;                      !!!!!!+---------ENABLE CRC
  87. ;                      !!!!!+----------ENABLE ALIGN
  88. ;                      !!!!+-----------ENABLE SHORT PKT
  89. ;                      !!!+------------DISABLE REMOTE RESET
  90. ;                      !!+-------------RESERVED
  91. ;                      !+--------------RESERVED
  92. ;                      +---------------ENABLE PKT READY
  93. ;
  94. xmit_mode       equ     00000010B
  95. ;
  96. ;ENABLE CARRIER DETECT
  97. ;
  98. ;DISABLE LOOPBACK
  99. ;
  100. recv_mode       equ     00000010B                 ; set receive mode
  101. ;
  102. ;                       !!!!!!!!---------ACCEPT ALL PACKETS
  103. ;                       !!!!!!!+---------ACCEPT PHYSICAL, MULTICAST, AND
  104. ;                       !!!!!!+----------BROADCAST PACKETS
  105. ;                       !!!!!+-----------DISABLE REMOTE RESET
  106. ;                       !!!!+------------DISABLE SHORT PACKETS
  107. ;                       !!!+-------------USE 6 BYTE ADDRESS
  108. ;                       !!+--------------NC
  109. ;                       !+---------------NC
  110. ;                       +----------------DISABLE CRC TEST MODE
  111.  
  112. debug    = 0
  113.  
  114.     include defs.asm
  115.  
  116. code segment word public
  117.     assume  cs:code, ds:code
  118.  
  119.     public  int_no
  120. int_no    db      3,0,0,0            ;must be four bytes long for get_number
  121. io_adr    dw    300h,0            ; default I/O address
  122. is_186    db      0            ; set to 1 if 186, 286, 386 word mode
  123.  
  124.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  125. driver_class    db      BLUEBOOK,IEEE8023,0    ;from the packet spec
  126. driver_type    db      1        ;from the packet spec
  127. driver_name    db      'TiaraFTP',0    ;name of the driver.
  128. driver_function    db    2
  129. parameter_list    label    byte
  130.     db    1    ;major rev of packet driver
  131.     db    9    ;minor rev of packet driver
  132.     db    14    ;length of parameter list
  133.     db    EADDR_LEN    ;length of MAC-layer address
  134.     dw    GIANT    ;MTU, including MAC headers
  135.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  136.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  137.     dw    0    ;(# of successive xmits) - 1
  138. int_num    dw    0    ;Interrupt # to hook for post-EOI
  139.             ;processing, 0 == none,
  140.  
  141.     public  rcv_modes
  142. rcv_modes    dw    7        ;number of receive modes in our table.
  143.         dw    0               ;There is no mode zero
  144.         dw    rcv_mode_1
  145.         dw    0
  146.         dw    rcv_mode_3
  147.         dw    0        ;haven't set up perfect filtering yet.
  148.         dw    0
  149.         dw    rcv_mode_6
  150.  
  151.  
  152. ;
  153. ;      Receive Packet Header Buffer: Required because addresses and e-type
  154. ;      must be read from Tiara card before upcall to find a buffer can be
  155. ;      made.  Need the number of bytes, and the e-type for the call...
  156. ;
  157. ether_buff    db    EADDR_LEN  dup(?)
  158.         db    EADDR_LEN  dup(?)
  159. ether_type    db    4 dup(?)
  160. usr_ptr        dd    ?                 ; temp storage or recv_buff ptr
  161.  
  162. writebport  macro   from_base,value
  163.     mov    dx,cs:[io_adr]        ; write byte value to port
  164.     add    dx,from_base
  165.     mov    al,value
  166.     out    dx,al
  167.     endm
  168.  
  169. ;sends $ terminated string to screen
  170. print$ macro   string
  171.     mov    ah,9
  172.     mov    dx,offset &string&    ; print $ terminated string
  173.     int    21h
  174.     endm
  175.  
  176. mark           = 0F90h                 ; marker debug pos on screen 25
  177.  
  178. marker  macro   st,nd
  179.   IF  debug NE 0                       ; do marker if debug <> 0
  180.       pushf                            ; show 2 char marker on
  181.       push es                          ; 25th line, 1st column
  182.       push ax
  183.       mov  ax,0B800h
  184.       mov  es,ax
  185.       mov  al,'&st&'
  186.       mov  byte ptr es:[mark],al
  187.       mov  al,byte ptr es:[mark+1]     ; get color value
  188.       inc  al
  189.       and  al,0Fh
  190.       or   al,1
  191.       mov  byte ptr es:[mark+1],al     ; advance it to show activity
  192.       mov  al,'&nd'
  193.       mov  byte ptr es:[mark+2],al
  194.       mov  al,byte ptr es:[mark+3]
  195.       inc  al
  196.       and  al,0Fh
  197.       or   al,1
  198.       mov  byte ptr es:[mark+3],al
  199.       pop  ax
  200.       pop  es
  201.       popf
  202.     ENDIF
  203.   endm
  204.  
  205.     public    as_send_pkt
  206. ; The Asynchronous Transmit Packet routine.
  207. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  208. ;   interrupts possibly enabled.
  209. ; Exit with nc if ok, or else cy if error, dh set to error number.
  210. ;   es:di and interrupt enable flag preserved on exit.
  211. as_send_pkt:
  212.     ret
  213.  
  214.     public    drop_pkt
  215. ; Drop a packet from the queue.
  216. ; Enter with es:di -> iocb.
  217. drop_pkt:
  218.     assume    ds:nothing
  219.     ret
  220.  
  221.     public    xmit
  222. ; Process a transmit interrupt with the least possible latency to achieve
  223. ;   back-to-back packet transmissions.
  224. ; May only use ax and dx.
  225. xmit:
  226.     assume    ds:nothing
  227.     ret
  228.  
  229.  
  230.     public    send_pkt
  231. send_pkt:
  232. ;enter with ds:si -> packet, cx = packet length.
  233. ;exit with nc if ok, pr else cy if error, dh set to error number.
  234.  
  235.               assume  ds:nothing
  236.               marker  T,X
  237.               inc     cx
  238.               and     cx,not 1                ; round to nearest even number
  239.               cmp     cx,RUNT                 ; big enough?
  240.               jae     send_runt_ok
  241.               mov     cx,RUNT                 ; at least runt!
  242. send_runt_ok:
  243.               cmp     cx,GIANT                ; small enough?
  244.               jle     send_size_ok
  245.               stc                             ; Error
  246.               ret
  247. send_size_ok:
  248.               push    cx
  249.               shr     cx,1                    ; words to send
  250. ;
  251. ;      8086/8088 byte mode send
  252. ;
  253.               mov     dx,cs:[io_adr]
  254.               add     dx,BMPR_MEM_PORT
  255.               cmp     cs:is_186,0  ; use BYTE or WORD mode?
  256.               jne     send_w_mode
  257.               cld
  258.  xb:
  259.               lodsw                           ; load word, ind ds:si
  260.               out     dx,al
  261.               xchg    ah,al
  262.               out     dx,al
  263.               loop    xb                      ; set packet length (byte mode)
  264.               pop     ax
  265.               or      ah,TMST
  266.               mov     dx,cs:[io_adr]
  267.               add     dx,BMPR_PKT_LEN
  268.               out     dx,al                   ; write BMPR2, then BMPR3 to
  269.               xchg    al,ah                   ; initiate byte mode transmit
  270.               inc     dx
  271.               out     dx,al
  272.               jmp     wait_tmt_ok
  273. send_w_mode:
  274.               cld
  275.               rep
  276.     db    0f3h, 06fh    ;masm 4.0 doesn't grok "rep outsw"
  277.               pop     ax
  278.               or      ah,TMST
  279.               mov     dx,cs:[io_adr]
  280.               add     dx,BMPR_PKT_LEN
  281.               out     dx,ax
  282. wait_tmt_ok:
  283.               xor     cx,cx
  284.               mov     dx,cs:[io_adr]
  285.               IF DLCR_XMIT_STAT NE 0
  286.                  add     dx,DLCR_XMIT_STAT
  287.               ENDIF
  288. wait_tmt:
  289.               in      al,dx            ; read status register until timeout...
  290.               test    al,TMT_OK
  291.               jnz     send_ok
  292.               loop    wait_tmt
  293.               stc
  294.               ret
  295. send_ok:
  296.               clc
  297.               ret
  298. public  get_address
  299. get_address:
  300.                                             ;get the address on the interface.
  301.     ;enter with es:di -> place to get the address, cx = size of address buffer
  302.     ;exit with nc, cx = actual size of address, or cy if buffer not big enough
  303.     ;
  304.               assume  ds:code
  305.               cmp     cx,EADDR_LEN                   ; enough room for address?
  306.               jge     get_adr_ok
  307.               stc
  308.               ret
  309. get_adr_ok:
  310.               mov     cx,EADDR_LEN
  311.               mov     dx,cs:[io_adr]         ; get address from PROM
  312.               add     dx,PROM_ID
  313.               cld
  314. get_adr:
  315.               in      al,dx
  316.               inc     dx
  317.               stosb
  318.               loop    get_adr
  319.               mov     cx,EADDR_LEN
  320.               clc
  321.               ret
  322.  
  323.  
  324.     public  set_address
  325. set_address:
  326. ;enter with ds:si -> Ethernet address,CX = length of address.
  327. ;exit with nc if okay, or cy, dh=error if any errors.
  328.     assume    ds:nothing
  329.     ret
  330.  
  331.  
  332. rcv_mode_1:
  333.     writebport    DLCR_RECV_MODE,0    ; don't receive any packets
  334.     ret
  335.  
  336.  
  337. rcv_mode_3:
  338.     writebport    DLCR_RECV_MODE,2    ; receive mine, broads, and multis.
  339.     ret
  340.  
  341.  
  342. rcv_mode_6:
  343.     writebport    DLCR_RECV_MODE,3    ; receive all packets.
  344.     ret
  345.  
  346.  
  347.     public  set_multicast_list
  348. set_multicast_list:
  349. ;enter with es:di ->list of multicast addresses, cx = number of bytes.
  350. ;return nc if we set all of them, or cy,dh=error if we didn't.
  351.  
  352.     mov     dh,NO_MULTICAST
  353.     stc
  354.     ret
  355.  
  356.     public  get_multicast_list
  357. get_multicast_list:
  358. ;return with nc, es:di ->list of multicast addresses, cx = number of bytes.
  359. ;return cy, NO_ERROR if we don't remember all of the addresses ourselves.
  360. ;return cy, NO_MULTICAST if we don't implement multicast.
  361.  
  362.     mov     dh,NO_MULTICAST
  363.     stc
  364.     ret
  365.  
  366.     public    terminate
  367. terminate:
  368.     writebport    DLCR_RECV_MODE,0    ; don't receive any packets
  369.     ret
  370.  
  371.     public  reset_interface
  372. reset_interface:                       ;reset the interface.
  373.     assume  ds:code
  374.     ret
  375.  
  376. ;called when we want to determine what to do with a received packet.
  377. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  378.     extrn   recv_find: near
  379.  
  380. ;called after we've copied the packet into the buffer.
  381. ;enter with ds:si ->the packet, cx = length of the packet.
  382.     extrn   recv_copy: near
  383.  
  384.     extrn   count_in_err: near
  385.     extrn   count_out_err: near
  386.  
  387.     public  recv
  388. recv:
  389. ;called from the recv isr.  All registers have been saved, and ds=cs.
  390. ;Upon exit, the interrupt will be acknowledged.
  391.  
  392.     assume  ds:code
  393.     marker  R,X
  394.  
  395. ;clear receive masks to prevent further IRQs
  396.  
  397.     writebport    DLCR_RECV_MASK,0
  398.     cli
  399. recv_0:
  400.     mov     ax,cs
  401.     mov     ds,ax
  402.     writebport      DLCR_RECV_STAT,clr_rcv_status
  403.  
  404. ;are there any packets to read?
  405.  
  406.     mov     dx,cs:[io_adr]
  407.     add     dx,DLCR_RECV_MODE
  408.     in      al,dx
  409.     test    al,BUF_EMPTY
  410.     jz      recv_1                    ; 0 if at least one valid pkt..
  411.     jmp     recv_99
  412.  
  413. ;yes, read out a receive packet...
  414.  
  415. recv_1:
  416.               cmp     cs:is_186,0
  417.               jne     recv11
  418.               jmp     read_b_mode
  419. ;
  420. ;        read packet out in word mode
  421. ;
  422. recv11:
  423.     mov    dx,cs:[io_adr]    ; get status and reserved byte
  424.     add    dx,BMPR_MEM_PORT
  425.     in    ax,dx
  426.     in    ax,dx                           ; get packet size
  427.     inc    ax                              ; convert to words
  428.     and    ax,not 1                        ; save it for copy out...
  429.     push    ax
  430.                     ;read first 14 bytes from receive buffer into ether_buff
  431.     mov    ax,cs
  432.     mov    es, ax
  433.     mov    di,offset ether_buff
  434.     mov    cx,16/2                            ; word mode, remember...
  435.     cld
  436. ;    rep    insw            ; read words into ether_buff
  437.     db    0f3h, 06dh    ;masm 4.0 doesn't grok "rep insw"
  438.  
  439. ;
  440. ;      If the sender is myself, ignore the packet.  This allows async
  441. ;      send/receive without messing up...
  442. ;
  443.     mov    si,offset ether_buff+EADDR_LEN       ; we want the SOURCE
  444.     mov    dx,cs:io_adr
  445.     add    dx,PROM_ID
  446.     mov    cx,EADDR_LEN
  447. my_send:
  448.     in    al, dx
  449.     inc    dx
  450.     cmp    al,byte ptr ds:[si]
  451.     jne    not_mine
  452.     inc    si
  453.     loop    my_send
  454.     jmp    word_flush                      ; mine, so flush it
  455. ;
  456. ;      cx = length, es:di = pointer to ethertype
  457. ;
  458. not_mine:
  459.     pop    cx
  460.     push    cx
  461.     mov    di,offset ether_type
  462.     mov    ax,cs
  463.     mov    es,ax            ; es:di -> ether type, cx = size# bytes
  464.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  465.     mov    ax, es:[di]
  466.     xchg    ah, al
  467.     cmp     ax, 1500
  468.     ja    BlueBookPacket
  469.     inc    di            ;set di to 802.2 header
  470.     inc    di
  471.     mov    dl, IEEE8023
  472. BlueBookPacket:
  473.     call    recv_find        ; got a buffer?
  474.     mov    ax,es
  475.     or    ax,di            ; pointer zero?
  476.     je    word_flush        ; no pointer, discard data
  477. ;
  478. ;      es:di -> users buffer, do copy...
  479. ;      ds:si -> source of copy
  480. ;
  481.     mov    cs:[usr_ptr.segm],es; save ULP pointer
  482.     mov    cs:[usr_ptr.offs],di
  483.     mov    ax,cs
  484.     mov    ds,ax
  485.     mov    si,offset ether_buff    ; copy header to users buffer
  486.     mov    cx,16/2            ; 8 words to copy
  487.     cld
  488.     rep    movsw
  489.     mov    dx,cs:[io_adr]        ;copy rest of data to user
  490.     add    dx,BMPR_MEM_PORT    ; buffer in es:di ->
  491.     pop    cx
  492.     push    cx
  493.     sub    cx,16
  494.     shr    cx,1
  495.     cld
  496. ;    rep    insw            ; read word, store at es:di ->
  497.     db    0f3h, 06dh    ;masm 4.0 doesn't grok "rep insw"
  498.     pop    cx            ;call recv_copy to say copy done
  499.     lds    si,cs:[usr_ptr]
  500.     call    recv_copy
  501.     jmp    recv_0            ; go get another packet
  502. word_flush:
  503.     mov    dx,cs:[io_adr]
  504.     add    dx,BMPR_MEM_PORT
  505.     pop    cx
  506.     sub    cx,16            ; adjust word count
  507.     shr    cx,1
  508. word_f:
  509.     in    ax,dx
  510.     loop    word_f
  511.     jmp    recv_0
  512. ;
  513. ;             go see of any more packets comming....
  514. ;
  515. ;             READ in BYTE MODE
  516. ;
  517. read_b_mode:
  518.     mov    dx,cs:[io_adr]    ;get status and reserved byte
  519.     add    dx,BMPR_MEM_PORT
  520.     in    al,dx        ; vacuum status and reserved
  521.     in    al,dx
  522.     in    al,dx        ; get packet size
  523.     xchg    al,ah        ; low byte in ah
  524.     in    al,dx        ; get packet size
  525.     xchg    al,ah        ; fix size ah/al order
  526.     push    ax        ; keep number of bytes
  527.     ;      read first 16 bytes from receive buffer into ether_buff
  528.     mov    ax,cs
  529.     mov    es,ax
  530.     mov    di,offset ether_buff
  531.     mov    cx,16            ; byte mode, 16 byte header
  532.     cld
  533. rdb:
  534.     in    al,dx            ; read 16 bytes into ether_buff
  535.     stosb
  536.     loop    rdb
  537. ;
  538. ;      If the sender is myself, ignore the packet.
  539. ;
  540.     mov    si,offset ether_buff+EADDR_LEN; we want the SOURCE...
  541.     mov    dx,cs:[io_adr]
  542.     add    dx,PROM_ID
  543.     mov    cx,EADDR_LEN
  544. my_sendb:
  545.     in    al,dx
  546.     inc    dx
  547.     cmp    al,byte ptr ds:[si]
  548.     jne    not_mineb
  549.     inc    si
  550.     loop    my_sendb
  551.     jmp    byte_flush                  ; mine, so flush it
  552. ;
  553. ;      cx = length, es:di = pointer to ethertype
  554. ;
  555. not_mineb:
  556.     pop    cx
  557.     push    cx
  558.     mov    di,offset ether_type
  559.     mov    ax,cs
  560.     mov    es,ax             ; es:di -> ether type, cx = size#bytes
  561.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  562.     mov    ax, es:[di]
  563.     xchg    ah, al
  564.     cmp     ax, 1500
  565.     ja    BlueBookPacket1
  566.     inc    di            ;set di to 802.2 header
  567.     inc    di
  568.     mov    dl, IEEE8023
  569. BlueBookPacket1:
  570.     call    recv_find                   ; got a buffer?
  571.     mov    ax,es
  572.     or    ax,di                       ; pointer zero?
  573.     je    byte_flush                  ; no pointer, discard data
  574. ;
  575. ;      es:di -> users buffer, do copy...
  576. ;      ds:si -> source of copy
  577. ;
  578.     mov    cs:[usr_ptr.segm],es    ; save ULP pointer
  579.     mov    cs:[usr_ptr.offs],di
  580.     mov    ax,cs
  581.     mov    ds,ax
  582.     mov    si,offset ether_buff        ; copy header to users buffer
  583.     mov    cx,16                       ; 16 bytes in header to copy
  584.     cld
  585.     rep
  586.     movsb
  587.     mov    dx,cs:io_adr     ; copy rest of data to users
  588.     add    dx,BMPR_MEM_PORT            ; buffer in es:di ->
  589.     pop    cx
  590.     push    cx
  591.     sub    cx,14
  592.     cld
  593. cpyb:
  594.     in    al,dx            ; read byte
  595.     stosb                ; store at es:di ->
  596.     loop    cpyb
  597.     pop    cx            ; call recv_copy to say copy done
  598.     lds    si,cs:[usr_ptr]
  599.     call    recv_copy
  600.     jmp    recv_0            ; go get another packet...
  601. byte_flush:
  602.     mov    dx,cs:io_adr
  603.     add    dx,BMPR_MEM_PORT
  604.     pop    cx
  605.     sub    cx,16            ; adjust byte count header
  606. byte_f:
  607.     in    al,dx
  608.     loop    byte_f
  609.     jmp    recv_0            ; go to see if any more packets comming...
  610. recv_99:
  611. ;      receive ok, restore recive mask and exit
  612. ;
  613.     writebport    DLCR_RECV_MASK,en_rcv_irqs
  614.     ret
  615.  
  616.  
  617.     public    recv_exiting
  618. recv_exiting:
  619. ;called from the recv is after interrupts have been acknowledged.
  620. ;Only ds and ax have been saved.
  621. ;
  622.     assume    ds:nothing
  623.     ret
  624.  
  625. ;any code after this will not be kept after initialization.
  626.  
  627. end_resident    label    byte
  628.  
  629. io_adr_msg    db    "I/O Base Address: ",'$'
  630. int_no_msg    db    " Interrupt Level: ",'$'
  631. no_card_msg    db    "INIT: No card at I/O address specified",CR,LF,'$'
  632. is_186_msg    db    "INIT: Using WORD I/O mode.",CR,LF,'$'
  633. not_186_msg    db    "INIT: Using BYTE I/O mode.",CR,LF,'$'
  634. installed_ok    db    "INIT: Installation Complete",CR,LF,'$'
  635.  
  636.     public  usage_msg
  637. usage_msg   db  "usage: TiaraFTP [-n] [-d] [-w] <packet_int_no> <int_no> <io_adr>",CR,LF,'$'
  638.  
  639.     public  copyright_msg
  640. copyright_msg    label    byte
  641.  db CR,LF
  642.  db "TiaraFTP:  Driver for Tiara Card, Version ",'0'+majver,".",'0'+version, CR,LF
  643.  db "         - for PC, PC-AT, and Micro Channel (IBM tm)",CR,LF
  644.  db "portions - Copyright 1990, 1991 Queens University",CR,LF
  645.  db "    Written by Brian Fisher",CR,LF
  646.  db CR,LF,'$'
  647.  
  648.     extrn   set_recv_isr: near
  649. ;enter with si-> argument string,di->wword to store.
  650. ;if there is no number, don't change  the number.
  651.  
  652. ;enter with si -> argument string, di -> word to store.
  653. ;if there is no number, don't change the number.
  654.     extrn   get_number: near
  655.  
  656. ;enter with dx -> name of word, di -> dword to print.
  657.     extrn    print_number: near
  658.  
  659.  
  660. ;==============================================================================;
  661. ;========================= MICROCHANNEL SUPPORT ===============================;
  662. ;==============================================================================;
  663.  
  664. POS_max         equ     7h              ; max number of slots to check
  665.  
  666. POS_select      equ     096h            ; POS Select register location
  667. POS_mask        equ     008h            ; POS Select mask
  668.  
  669. POS_0           equ     100h            ; POS Registers
  670. POS_1           equ     101h
  671. POS_2           equ     102h
  672.  
  673. ;       Card Specific Items
  674.  
  675. Adapter_ID      equ     6001h           ; POS_0 | POS_1
  676.  
  677. Adapter_open    equ     00000001b       ; POS_2
  678. ;                       ||||||||
  679. ;                       |||||||+-------- 1 = card enabled (open)
  680. ;                       ||||||+--------- 1 = Boot Prom Enable
  681. ;                       |||||+---------- } IRQ Level Select
  682. ;                       ||||+----------- } IRQ Level Select
  683. ;                       |||+------------ )
  684. ;                       ||+------------- ) I/O Port Base Address Select
  685. ;                       |+-------------- )
  686. ;                       +--------------- )
  687.  
  688. ; Adapter Boot PROM is disabled for this configuration, so POS_5 has no
  689. ; meaning, and is ignored.
  690.  
  691. irq_list       dw       3              ;  00h    POS_2 after [POS_2]&0Ch
  692.                dw       4              ;  04h
  693.                dw       7              ;  08h
  694.                dw       9              ;  0Ch
  695.  
  696. io_list        dw       1200h          ; MCH I/O Address List
  697.                dw       1220h
  698.                dw       1240h
  699.                dw       1260h
  700.                dw       1280h
  701.                dw       12A0h
  702.                dw       12C0h
  703.                dw       12E0h
  704.                dw       1300h
  705.                dw       1320h
  706.                dw       1340h
  707.                dw       1360h
  708.                dw       1380h
  709.                dw       13A0h
  710.                dw       13C0h
  711.                dw       13E0h
  712.  
  713. mch_found      db      "INIT: This machine has a MICROCHANNEL card.",CR,LF,'$'
  714.  
  715.  
  716.     public  parse_args
  717. parse_args:
  718. ;
  719. ;      Look for MicroChannel POS information, and if found, set default
  720. ;      values for I/O base address and IRQ level before parsing the
  721. ;      command line.
  722. ;
  723.         pushf                  ; save flags
  724.         cli                    ; no IRQ's during this phase
  725.  
  726.         mov     cx,POS_max+1   ; start with the last slot first...
  727.         mov     dx,POS_select
  728.         in      al,dx          ; Save old POS_select value
  729.         push    ax
  730.  
  731. mch_chk:
  732.         mov     al,cl          ; get slot count
  733.         dec     al             ; adjust it
  734.         or      al,POS_mask    ; add the mask
  735.         mov     dx,POS_select
  736.         out     dx,al          ; write select value
  737.  
  738.         mov     dx,POS_1       ; read the Adapter_id
  739.         in      al,dx          ; get hi byte
  740.         xchg    al,ah
  741.         dec     dx
  742.         in      al,dx          ; get lo byte
  743.         cmp     ax,Adapter_id  ; did I find the card?
  744.         je      mch_chk_match  ; yes...
  745.         loop    mch_chk
  746.  
  747. ;       use this to leave microchannel POS_select as we found it...
  748.         pop     ax
  749.         mov     dx,POS_select
  750.         out     dx,al
  751.         popf
  752.         jmp     parse_start
  753.  
  754. mch_chk_match:
  755. ;       parse I/O base address and interrupt level from POS_2 data
  756.         mov     dx,POS_2
  757.         in      al,dx
  758. ;
  759. ;       determine interrupt level
  760.         and     al,0Ch                  ; bits 2,3 are IRQ level
  761.         mov     cl,1
  762.         shr     al,cl                   ; index for irq_list
  763.         xor     ah,ah
  764.         mov     bx,ax
  765.         mov     ax,word ptr [bx+offset irq_list]
  766.         mov     word ptr int_no,ax
  767.  
  768.         in      al,dx                   ; read POS_2 again
  769.         and     al,0F0h                 ; get index into io_list
  770.         mov     cl,3
  771.         shr     al,cl
  772.         xor     ah,ah
  773.         mov     bx,ax
  774.         mov     ax,word ptr [bx+offset io_list]
  775.         mov     word ptr io_adr,ax
  776.  
  777.         pop     ax
  778.         mov     dx,POS_select
  779.         out     dx,al
  780.         popf
  781.         print$  mch_found
  782.  
  783. parse_start:
  784.  
  785. ;      parse I/O base address and hardware interrupt number from the
  786. ;      command line.
  787. ;
  788.     mov    bx,offset io_adr_msg    ; first comes the I/O base address
  789.     mov    di,offset io_adr
  790.     call    get_number
  791.     jc    _parse_exit
  792.     mov    bx,offset int_no_msg    ; interrupt level?
  793.     mov    di,offset int_no
  794.     call    get_number
  795. _parse_exit:
  796.     clc
  797.     ret
  798.  
  799. ;==============================================================================;
  800. ;==================== MICROCHANNEL SUPPORT ENDS ===============================;
  801. ;==============================================================================;
  802.  
  803.     public etopen
  804. etopen:
  805.     writebport    DLCR_ENABLE,card_disable    ; disable etherstar
  806.     writebport    DLCR_XMIT_STAT,clear_status    ; clr xmit status
  807.     writebport    DLCR_XMIT_MASK,no_tx_irqs    ; disable xmit IRQ's
  808.     writebport    DLCR_RECV_STAT,clr_rcv_status    ; clear rcv status
  809.     writebport    DLCR_RECV_MASK,en_rcv_irqs    ; enable rcv IRQ's
  810.     writebport    DLCR_XMIT_MODE,xmit_mode    ; set xmit mode
  811.     writebport    DLCR_RECV_MODE,recv_mode    ; set receive mode
  812. ;
  813. ;      Set Node ID:
  814. ;
  815.     mov    cx,EADDR_LEN        ; calc base of I/O regs for node id
  816.     mov    bx,cs:io_adr
  817.     mov    dx,bx
  818.     add    bx,DLCR_NODE_ID
  819.     add    dx,PROM_ID        ; and base of PROM for copy
  820. etopen0:
  821.     in    al,dx            ; read byte of factory address
  822.     xchg    bx,dx
  823.     out    dx,al            ; write to register
  824.     xchg    bx,dx
  825.     inc    dx
  826.     inc    bx
  827.     loop    etopen0            ; until copy is done...
  828. ;
  829. ;      Verify card exists by comparing address to PROM
  830. ;
  831.     mov    cx,EADDR_LEN
  832. etopen1:
  833.     dec    dx
  834.     dec    bx
  835.     in    al,dx
  836.     xchg    bx,dx
  837.     mov    ah,al
  838.     in    al,dx
  839.     xchg    bx,dx
  840.     cmp    al,ah
  841.     jne    etopen_nocard        ; no card found
  842.     loop    etopen1
  843.  
  844. ;Determine the processor type.  The 8088 and 8086 will actually shift ax
  845. ;over by 33 bits, while the 80[123]86 use a shift count mod 32.
  846.  
  847.     mov    cl,33
  848.     mov    ax,0ffffh
  849.     shl    ax,cl            ; Thanks to Russ Nelson for this little
  850.     jz    not_186            ; bit of 'clip art'.
  851.     mov    is_186,1
  852.     print$    is_186_msg
  853.     jmp    etopen2
  854. not_186:
  855.     print$  not_186_msg
  856. etopen2:
  857.                     ; vacuum data port until BUF_EMPTY
  858.     mov    dx,cs:io_adr
  859.     mov    bx,dx
  860.     add    bx,DLCR_RECV_MODE
  861.     add    dx,BMPR_MEM_PORT
  862.     cmp    cs:is_186,0
  863.     je    vac_88
  864. vac_86:
  865.     in    ax,dx
  866.     xchg    dx,bx
  867.     in    ax,dx
  868.     xchg    dx,bx
  869.     test    al,BUF_EMPTY
  870.     jz    vac_86
  871.     jmp    all_done
  872. vac_88:
  873.     in    al,dx
  874.     xchg    dx,bx
  875.     in    al,dx
  876.     xchg    dx,bx
  877.     test    al,BUF_EMPTY
  878.     jz    vac_88
  879. all_done:
  880.     writebport    DLCR_ENABLE,card_enable
  881.     call    set_recv_isr                ; install receive IRQ routine
  882.  
  883.     mov    al, int_no        ; Get board's interrupt vector
  884.     add    al, 8
  885.     cmp    al, 8+8            ; Is it a slave 8259 interrupt?
  886.     jb    set_int_num        ; No.
  887.     add    al, 70h - 8 - 8        ; Map it to the real interrupt.
  888. set_int_num:
  889.     xor    ah, ah            ; Clear high byte
  890.     mov    int_num, ax        ; Set parameter_list int num.
  891.  
  892.     print$    installed_ok                ; if all is okay,
  893.     mov    dx,offset end_resident
  894.     clc
  895.     ret
  896. etopen_nocard:
  897.     print$  no_card_msg              ; couldn't verify card exists...
  898.     stc
  899.     ret
  900.  
  901.     public    print_parameters
  902. print_parameters:
  903. ;echo our command-line parameters
  904.     mov    di,offset io_adr    ; first comes the I/O base address
  905.     mov    dx,offset io_adr_msg
  906.     call    print_number
  907.     mov    di,offset int_no    ; interrupt level?
  908.     mov    dx,offset int_no_msg
  909.     call    print_number
  910.     ret
  911.  
  912. code    ends
  913.  
  914.     end
  915.